package com.atguigu.tingshu.order.pattern.impl;

import cn.hutool.core.lang.Assert;
import com.atguigu.tingshu.album.AlbumFeignClient;
import com.atguigu.tingshu.common.constant.SystemConstant;
import com.atguigu.tingshu.common.util.AuthContextHolder;
import com.atguigu.tingshu.model.album.AlbumInfo;
import com.atguigu.tingshu.order.pattern.AbstractOrderConfirmPolicy;
import com.atguigu.tingshu.order.pattern.OrderConfirmPolicy;
import com.atguigu.tingshu.user.client.UserFeignClient;
import com.atguigu.tingshu.vo.order.OrderDerateVo;
import com.atguigu.tingshu.vo.order.OrderDetailVo;
import com.atguigu.tingshu.vo.order.OrderInfoVo;
import com.atguigu.tingshu.vo.order.TradeVo;
import com.atguigu.tingshu.vo.user.UserInfoVo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

@Component("1001")
public class AlbumOrderConfirm extends AbstractOrderConfirmPolicy {

    @Autowired
    private UserFeignClient userFeignClient;
    @Autowired
    private AlbumFeignClient albumFeignClient;

    @Override
    public OrderInfoVo confirm(TradeVo tradeVo,Long userId) {
        OrderInfoVo orderInfoVo = new OrderInfoVo();
        BigDecimal originalAmount = new BigDecimal("0.00");
        BigDecimal orderAmount = new BigDecimal("0.00");
        BigDecimal derateAmount = new BigDecimal("0.00");
        List<OrderDetailVo> orderDetailVoList = new ArrayList<>();
        List<OrderDerateVo> orderDerateVoList = new ArrayList<>();

        //远程调用用户服务调用,判断是否重复购买
        Long albumId = tradeVo.getItemId();
        Boolean isPaidAlbum = userFeignClient.isPaidAlbum(albumId).getData();
        Assert.isFalse(isPaidAlbum, "用户已购买专辑{}", albumId);
        //远程调用专辑服务,查询专辑价格和折扣信息
        AlbumInfo albumInfo = albumFeignClient.getAlbumInfo(albumId).getData();
        Assert.notNull(albumInfo, "专辑{}不存在", albumId);
        BigDecimal price = albumInfo.getPrice();
        BigDecimal discount = albumInfo.getDiscount();
        BigDecimal vipDiscount = albumInfo.getVipDiscount();
        //获取用户身份,判断是否使用折扣
        UserInfoVo userInfoVo = userFeignClient.getUserInfoVo(userId).getData();
        Assert.notNull(userInfoVo, "用户{}不存在", userId);
        if (userInfoVo.getIsVip().intValue() == 1 && userInfoVo.getVipExpireTime().after(new Date())) {
            //VIP用户折扣计算
            if (vipDiscount.intValue() != -1) {
                orderAmount = originalAmount.multiply(vipDiscount)
                        .divide(new BigDecimal("10"), 2, RoundingMode.HALF_UP);
            }
            originalAmount = price;
            orderAmount = originalAmount;
        } else if (userInfoVo.getIsVip().intValue() == 0 || userInfoVo.getVipExpireTime().before(new Date())) {
            //普通用户折扣计算
            if (discount.intValue() != -1) {
                orderAmount = originalAmount.multiply(discount)
                        .divide(new BigDecimal("10"), 2, RoundingMode.HALF_UP);
            }
            originalAmount = price;
            orderAmount = originalAmount;
        }
        //封装商品信息
        OrderDetailVo orderDetailVo = new OrderDetailVo();
        orderDetailVo.setItemId(albumId);
        orderDetailVo.setItemName("专辑: " + albumInfo.getAlbumTitle());
        orderDetailVo.setItemPrice(originalAmount);
        orderDetailVo.setItemUrl(albumInfo.getCoverUrl());
        orderDetailVoList.add(orderDetailVo);
        //封装商品优惠信息
        if (originalAmount.compareTo(orderAmount) == 1) {
            derateAmount = originalAmount.subtract(orderAmount);
            OrderDerateVo orderDerateVo = new OrderDerateVo();
            orderDerateVo.setDerateType(SystemConstant.ORDER_DERATE_ALBUM_DISCOUNT);
            orderDerateVo.setDerateAmount(derateAmount);
            orderDerateVo.setRemarks("专辑折扣减免：" + derateAmount);
            orderDerateVoList.add(orderDerateVo);
        }

        //封装订单价格信息
        orderInfoVo.setOriginalAmount(originalAmount);
        orderInfoVo.setOrderAmount(orderAmount);
        orderInfoVo.setDerateAmount(derateAmount);
        orderInfoVo.setOrderDetailVoList(orderDetailVoList);
        orderInfoVo.setOrderDerateVoList(orderDerateVoList);

        orderInfoVo.setItemType(tradeVo.getItemType());

        this.tradeNo(orderInfoVo,userId);
        this.tradeSign(orderInfoVo);

        return orderInfoVo;
    }
}
